<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="../">
<head>
  <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Prolog integration and migration &mdash; The Logtalk Handbook v3.93.0-b01 documentation</title>
      <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d75fae25" />
      <link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=19f00094" />
      <link rel="stylesheet" type="text/css" href="../_static/css/custom.css?v=396eccfe" />

  
  <!--[if lt IE 9]>
    <script src="../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
        <script src="../_static/jquery.js?v=5d32c60e"></script>
        <script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
        <script src="../_static/documentation_options.js?v=c8100655"></script>
        <script src="../_static/doctools.js?v=9a2dae69"></script>
        <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="../_static/js/theme.js"></script>
    <!-- begin favicon -->
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
    <link rel="manifest" href="/site.webmanifest" />
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
    <meta name="msapplication-TileColor" content="#355b95" />
    <meta name="theme-color" content="#ffffff" />
    <!-- end favicon -->
    
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Reference Manual" href="../refman/index.html" />
    <link rel="prev" title="Installing Logtalk" href="installing.html" />
   
</head>

<body class="wy-body-for-nav"> 
  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >

          
          
          <a href="../index.html" class="icon icon-home">
            The Logtalk Handbook
              <img src="../_static/logtalk.gif" class="logo" alt="Logo"/>
          </a>
              <div class="version">
                3.93.0
              </div>
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
    
              <p class="caption" role="heading"><span class="caption-text">Contents</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="index.html">User Manual</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="declarative.html">Declarative object-oriented programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="features.html">Main features</a></li>
<li class="toctree-l2"><a class="reference internal" href="nomenclature.html">Nomenclature</a></li>
<li class="toctree-l2"><a class="reference internal" href="messages.html">Messages</a></li>
<li class="toctree-l2"><a class="reference internal" href="objects.html">Objects</a></li>
<li class="toctree-l2"><a class="reference internal" href="protocols.html">Protocols</a></li>
<li class="toctree-l2"><a class="reference internal" href="categories.html">Categories</a></li>
<li class="toctree-l2"><a class="reference internal" href="predicates.html">Predicates</a></li>
<li class="toctree-l2"><a class="reference internal" href="inheritance.html">Inheritance</a></li>
<li class="toctree-l2"><a class="reference internal" href="events.html">Event-driven programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="threads.html">Multi-threading programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="errors.html">Error handling</a></li>
<li class="toctree-l2"><a class="reference internal" href="reflection.html">Reflection</a></li>
<li class="toctree-l2"><a class="reference internal" href="programming.html">Writing and running applications</a></li>
<li class="toctree-l2"><a class="reference internal" href="printing.html">Printing messages and asking questions</a></li>
<li class="toctree-l2"><a class="reference internal" href="expansion.html">Term and goal expansion</a></li>
<li class="toctree-l2"><a class="reference internal" href="documenting.html">Documenting</a></li>
<li class="toctree-l2"><a class="reference internal" href="debugging.html">Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="performance.html">Performance</a></li>
<li class="toctree-l2"><a class="reference internal" href="installing.html">Installing Logtalk</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Prolog integration and migration</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#source-files-with-both-prolog-code-and-logtalk-code">Source files with both Prolog code and Logtalk code</a></li>
<li class="toctree-l3"><a class="reference internal" href="#encapsulating-plain-prolog-code-in-objects">Encapsulating plain Prolog code in objects</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#prolog-multifile-predicates">Prolog multifile predicates</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#converting-prolog-modules-into-objects">Converting Prolog modules into objects</a></li>
<li class="toctree-l3"><a class="reference internal" href="#compiling-prolog-modules-as-objects">Compiling Prolog modules as objects</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#supported-module-directives">Supported module directives</a></li>
<li class="toctree-l4"><a class="reference internal" href="#unsupported-module-directives">Unsupported module directives</a></li>
<li class="toctree-l4"><a class="reference internal" href="#modules-using-a-term-expansion-mechanism">Modules using a term-expansion mechanism</a></li>
<li class="toctree-l4"><a class="reference internal" href="#file-search-paths">File search paths</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#dealing-with-proprietary-prolog-directives-and-predicates">Dealing with proprietary Prolog directives and predicates</a></li>
<li class="toctree-l3"><a class="reference internal" href="#calling-prolog-module-predicates">Calling Prolog module predicates</a></li>
<li class="toctree-l3"><a class="reference internal" href="#loading-converted-prolog-applications">Loading converted Prolog applications</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../refman/index.html">Reference Manual</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial/index.html">Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../devtools/index.html">Developer Tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../libraries/index.html">Libraries</a></li>
<li class="toctree-l1"><a class="reference internal" href="../ports/index.html">Ports</a></li>
<li class="toctree-l1"><a class="reference internal" href="../contributions/index.html">Contributions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../bibliography.html">Bibliography</a></li>
<li class="toctree-l1"><a class="reference internal" href="../genindex.html">Index</a></li>
</ul>

    <p class="caption"><span class="caption-text">External Contents</span></p>
    <ul>
    <li class="toctree-l1"><a class="reference internal" href="../../apis/index.html">APIs</a></li>
    <li class="toctree-l1"><a class="reference internal" href="https://logtalk.org">Logtalk website</a></li>
    <li class="toctree-l1"><a class="reference internal" href="https://github.com/LogtalkDotOrg/logtalk3">GitHub repo</a></li>
    </ul>
  
        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../index.html">The Logtalk Handbook</a>
      </nav>

      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
          <li class="breadcrumb-item"><a href="index.html">User Manual</a></li>
      <li class="breadcrumb-item active">Prolog integration and migration</li>
      <li class="wy-breadcrumbs-aside">
              <a href="https://github.com/LogtalkDotOrg/logtalk3/blob/master/docs/handbook/sources/userman/migration.rst" class="fa fa-github"> Edit on GitHub</a>
      </li>
  </ul>
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
             
  <section id="prolog-integration-and-migration">
<span id="migration-migration"></span><h1>Prolog integration and migration<a class="headerlink" href="#prolog-integration-and-migration" title="Link to this heading"></a></h1>
<p>This section provides suggestions for integrating and migrating plain Prolog
code and Prolog module code to Logtalk. Detailed instructions are provided for
encapsulating plain Prolog code in objects, converting Prolog modules into
objects, and compiling and reusing Prolog modules as objects from inside
Logtalk. An interesting application of the techniques described in this
section is a solution for running a Prolog application that uses modules
on a Prolog compiler with no module system. The <a class="reference internal" href="../devtools/wrapper.html"><span class="doc">wrapper</span></a>
tool can be used to help in migrating Prolog code.</p>
<section id="source-files-with-both-prolog-code-and-logtalk-code">
<span id="migration-hybrid"></span><h2>Source files with both Prolog code and Logtalk code<a class="headerlink" href="#source-files-with-both-prolog-code-and-logtalk-code" title="Link to this heading"></a></h2>
<p>Logtalk source files may contain plain Prolog code intermixed with
Logtalk code. The Logtalk compiler simply copies the plain Prolog code
as-is to the generated Prolog file. With Prolog modules, it is assumed
that the module code starts with a <code class="docutils literal notranslate"><span class="pre">module/1-2</span></code> directive and ends at
the end of the file. There is no module ending directive that would
allow us to define more than one module per file. In fact, most, if not
all, Prolog module systems always define a single module per file. Some
of them mandate that the <code class="docutils literal notranslate"><span class="pre">module/1-2</span></code> directive be the first term in
a source file. As such, when the Logtalk compiler finds a <code class="docutils literal notranslate"><span class="pre">module/1-2</span></code>
directive, it assumes that all code that follows until the end of the
file belongs to the module.</p>
</section>
<section id="encapsulating-plain-prolog-code-in-objects">
<span id="migration-encapsulating"></span><h2>Encapsulating plain Prolog code in objects<a class="headerlink" href="#encapsulating-plain-prolog-code-in-objects" title="Link to this heading"></a></h2>
<p>Most applications consist of several plain Prolog source files, each one
defining a few top-level predicates and auxiliary predicates that are
not meant to be directly called by the user. Encapsulating plain Prolog
code in objects allows us to make clear the different roles of each
predicate, to hide implementation details, to prevent auxiliary
predicates from being called outside the object, and to take advantage
of Logtalk advanced code encapsulating and reusing features. It also
simplifies using its developer tools.</p>
<p>Encapsulating Prolog code using Logtalk objects is simple. First, for each
source file, add an opening object directive, <a class="reference internal" href="../refman/directives/object_1_5.html#directives-object-1-5"><span class="std std-ref">object/1-5</span></a>,
to the beginning of the file and an ending object directive,
<a class="reference internal" href="../refman/directives/end_object_0.html#directives-end-object-0"><span class="std std-ref">end_object/0</span></a>, to the end of
the file. Choose an object name that reflects the purpose of the source file
code (this is a good opportunity for code refactoring if necessary).
Second, add <a class="reference internal" href="../refman/directives/public_1.html#directives-public-1"><span class="std std-ref">public/1</span></a> predicate directives for the
top-level predicates that are used directly by the user or called from
other source files. Third, we need to be able to call from inside an object
predicates defined in other source files/objects. The easiest solution,
which has the advantage of not requiring any changes to the predicate
definitions, is to use the <a class="reference internal" href="../refman/directives/uses_2.html#directives-uses-2"><span class="std std-ref">uses/2</span></a> directive. If your
Prolog compiler supports cross-referencing tools, you may use them to
help you make sure that all calls to predicates on other source
files/objects are listed in the <a class="reference internal" href="../refman/directives/uses_2.html#directives-uses-2"><span class="std std-ref">uses/2</span></a> directives.
The Logtalk <code class="docutils literal notranslate"><span class="pre">wrapper</span></code> tool can also help in detecting cross-predicate
calls. Compiling the resulting objects with the Logtalk
<a class="reference internal" href="programming.html#flag-unknown-predicates"><span class="std std-ref">unknown_predicates</span></a> and
<a class="reference internal" href="programming.html#flag-portability"><span class="std std-ref">portability</span></a> flags set to <code class="docutils literal notranslate"><span class="pre">warning</span></code> will
help you identify calls to predicates defined in other converted source
files and possible portability issues.</p>
<section id="prolog-multifile-predicates">
<span id="migration-multifile"></span><h3>Prolog multifile predicates<a class="headerlink" href="#prolog-multifile-predicates" title="Link to this heading"></a></h3>
<p>Prolog <em>multifile</em> predicates are used when clauses for the same
predicate are spread among several source files. When encapsulating
plain Prolog code that uses multifile predicates, it’s often the case that
the clauses of the multifile predicates get spread between different
objects and categories, but conversion is straight-forward. In the
Logtalk object (or category) holding the multifile predicate
<a class="reference internal" href="../glossary.html#term-primary-predicate-declaration"><span class="xref std std-term">primary declaration</span></a>, add a
<a class="reference internal" href="predicates.html#predicates-scope"><span class="std std-ref">predicate scope directive</span></a> and a
<a class="reference internal" href="predicates.html#predicates-multifile"><span class="std std-ref">multifile/1</span></a> directive. In
all other objects (or categories) defining clauses for the multifile
predicate, add a <code class="docutils literal notranslate"><span class="pre">multifile/1</span></code> directive and predicate clauses using
the format:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">multifile</span>(<span class="nv">Entity</span><span class="o">::</span><span class="nv">Name</span><span class="o">/</span><span class="nv">Arity</span>).

<span class="nv">Entity</span><span class="o">::</span><span class="nv">Functor</span>(...) <span class="o">:-</span>
    ...
</pre></div>
</div>
<p>See the <a class="reference internal" href="predicates.html#predicates-multifile"><span class="std std-ref">section</span></a> on the <code class="docutils literal notranslate"><span class="pre">multifile/1</span></code>
predicate directive for more information. An alternative solution is to
simply keep the clauses for the multifile predicates as plain Prolog code
and define, if necessary, a parametric object to encapsulate all predicates
working with the multifile predicate clauses. For example, assume the
following <code class="docutils literal notranslate"><span class="pre">multifile/1</span></code> directive:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="c">% city(Name, District, Population, Neighbors)</span>
<span class="p">:- </span><span class="k">multifile</span>(city<span class="o">/</span><span class="m">4</span>).
</pre></div>
</div>
<p>We can define a parametric object with <code class="docutils literal notranslate"><span class="pre">city/4</span></code> as its identifier:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">object</span>(city(<span class="nv">_Name</span>, <span class="nv">_District</span>, <span class="nv">_Population</span>, <span class="nv">_Neighbors</span>)).

    <span class="c">% predicates for working with city/4 clauses</span>

<span class="p">:- </span><span class="k">end_object</span>.
</pre></div>
</div>
<p>This solution is preferred when the multifile predicates are used
to represent large tables of data. See the section on
<a class="reference internal" href="objects.html#objects-parametric"><span class="std std-ref">parametric objects</span></a> for more details.</p>
</section>
</section>
<section id="converting-prolog-modules-into-objects">
<span id="migration-converting"></span><h2>Converting Prolog modules into objects<a class="headerlink" href="#converting-prolog-modules-into-objects" title="Link to this heading"></a></h2>
<p>Converting Prolog modules into objects may allow an application to run
on a wider range of Prolog compilers, overcoming portability problems.
Some Prolog compilers don’t support a module system. Among those Prolog
compilers that support a module system, the lack of standardization
leads to several issues, notably with semantics, operators, and
meta-predicates. In addition, the conversion allows you to take
advantage of Logtalk more powerful abstraction and reuse mechanisms, such
as separation between interface and implementation, inheritance,
parametric objects, and categories. It also allows you to take full
advantage of Logtalk developer tools for improved productivity.</p>
<p>Converting a Prolog module into an object is simplified when the directives
used in the module are supported by Logtalk (see the listing in the next
section). Assuming that this is the case, apply the following steps:</p>
<ol class="arabic simple">
<li><p>Convert the module <code class="docutils literal notranslate"><span class="pre">module/1</span></code> directive into an
<a class="reference internal" href="../refman/directives/object_1_5.html#directives-object-1-5"><span class="std std-ref">object/1</span></a> opening object directive,
using the module name as the object name. For <code class="docutils literal notranslate"><span class="pre">module/2</span></code> directives
apply the same conversion and convert the list of exported predicates
into <a class="reference internal" href="../refman/directives/public_1.html#directives-public-1"><span class="std std-ref">public/1</span></a> predicate directives. Add a closing
object directive, <a class="reference internal" href="../refman/directives/end_object_0.html#directives-end-object-0"><span class="std std-ref">end_object/0</span></a>, at the end of the
source code.</p></li>
<li><p>Convert any <code class="docutils literal notranslate"><span class="pre">export/1</span></code> directives into <code class="docutils literal notranslate"><span class="pre">public/1</span></code> predicate
directives.</p></li>
<li><p>Convert any <code class="docutils literal notranslate"><span class="pre">use_module/1</span></code> directives for modules that will not be
converted to objects into <code class="docutils literal notranslate"><span class="pre">use_module/2</span></code> directives (see next section),
replacing the file spec in the first argument with the module name.</p></li>
<li><p>Convert any <code class="docutils literal notranslate"><span class="pre">use_module/1-2</span></code> directives referencing other modules
also being converted to objects into Logtalk <a class="reference internal" href="../refman/directives/uses_2.html#directives-uses-2"><span class="std std-ref">uses/2</span></a>
directives.</p></li>
<li><p>Convert each <code class="docutils literal notranslate"><span class="pre">reexport/1</span></code> directive into a <a class="reference internal" href="../refman/directives/uses_2.html#directives-uses-2"><span class="std std-ref">uses/2</span></a>
directive and <code class="docutils literal notranslate"><span class="pre">public/1</span></code> predicate directives (see next section).</p></li>
<li><p>Convert any <code class="docutils literal notranslate"><span class="pre">meta_predicate/1</span></code> directives into Logtalk
<a class="reference internal" href="../refman/directives/meta_predicate_1.html#directives-meta-predicate-1"><span class="std std-ref">meta_predicate/1</span></a> directives by replacing the module
meta-argument indicator, <code class="docutils literal notranslate"><span class="pre">:</span></code>, with the Logtalk meta-argument indicator
<code class="docutils literal notranslate"><span class="pre">0</span></code> for goal meta-arguments. For closure meta-arguments, use an integer
denoting the number of additional arguments that will be appended to
construct a goal. Arguments that are not meta-arguments are represented by
the <code class="docutils literal notranslate"><span class="pre">*</span></code> character. Do not use argument mode indicators such as <code class="docutils literal notranslate"><span class="pre">?</span></code>, or
<code class="docutils literal notranslate"><span class="pre">+</span></code>, or <code class="docutils literal notranslate"><span class="pre">-</span></code> as Logtalk supports <a class="reference internal" href="predicates.html#predicates-mode"><span class="std std-ref">mode directives</span></a>.</p></li>
<li><p>Convert any explicit qualified calls to module predicates to messages
by replacing the <code class="docutils literal notranslate"><span class="pre">(:)/2</span></code> operator with the <a class="reference internal" href="../refman/control/send_to_object_2.html#control-send-to-object-2"><span class="std std-ref">(::)/2</span></a>
message-sending operator when the referenced modules are also being
converted into objects. Calls in the pseudo-module <code class="docutils literal notranslate"><span class="pre">user</span></code> can be
encapsulated using the <a class="reference internal" href="../refman/control/external_call_1.html#control-external-call-1"><span class="std std-ref">{}/1</span></a> Logtalk external
call control construct. You can also use instead a <a class="reference internal" href="../refman/directives/uses_2.html#directives-uses-2"><span class="std std-ref">uses/2</span></a>
directive where the first argument would be the atom <code class="docutils literal notranslate"><span class="pre">user</span></code> and the
second argument a list of all external predicates. This alternative has
the advantages of not requiring changes to the code making the predicate
calls and of better visibility for the documenting and diagramming tools.</p></li>
<li><p>If your module uses the database built-in predicates to implement
module-local mutable state using dynamic predicates, add both
<a class="reference internal" href="../refman/directives/private_1.html#directives-private-1"><span class="std std-ref">private/1</span></a> and
<a class="reference internal" href="../refman/directives/dynamic_1.html#directives-dynamic-1"><span class="std std-ref">dynamic/1</span></a> directives
for each dynamic predicate.</p></li>
<li><p>If your module declares or defines clauses for multifile module
predicates, replace the <code class="docutils literal notranslate"><span class="pre">(:)/2</span></code> functor by <code class="docutils literal notranslate"><span class="pre">(::)/2</span></code> in the
<code class="docutils literal notranslate"><span class="pre">multifile/1</span></code> directives and in the clause heads for all modules
defining the multifile predicates that are also being converted into
objects; if that is not the case, just keep the <code class="docutils literal notranslate"><span class="pre">multifile/1</span></code>
directives and the clause heads as-is.</p></li>
<li><p>Compile the resulting objects with the Logtalk
<a class="reference internal" href="programming.html#flag-unknown-predicates"><span class="std std-ref">unknown_predicates</span></a>, and
<a class="reference internal" href="programming.html#flag-portability"><span class="std std-ref">portability</span></a> flags set to <code class="docutils literal notranslate"><span class="pre">warning</span></code>
to help you locate possible issues and calls to proprietary Prolog
built-in predicates and to predicates defined on other converted
modules. In order to improve code portability, check the Logtalk
library for possible alternatives to the use of proprietary Prolog
built-in predicates.</p></li>
</ol>
<p>Before converting your modules to objects, you may try to compile them
first as objects (using the <a class="reference internal" href="../refman/predicates/logtalk_compile_1.html#predicates-logtalk-compile-1"><span class="std std-ref">logtalk_compile/1</span></a>
Logtalk built-in predicates) to help identify any issues that must be
dealt with when doing the conversion to objects. Note that Logtalk
supports compiling Prolog files as Logtalk source code without requiring
changes to the file name extensions.</p>
</section>
<section id="compiling-prolog-modules-as-objects">
<span id="migration-compiling"></span><h2>Compiling Prolog modules as objects<a class="headerlink" href="#compiling-prolog-modules-as-objects" title="Link to this heading"></a></h2>
<p>A possible alternative to porting Prolog code to Logtalk is to compile the Prolog
source files using the <code class="docutils literal notranslate"><span class="pre">logtalk_load/1-2</span></code> and <code class="docutils literal notranslate"><span class="pre">logtalk_compile/1-2</span></code>
predicates. The Logtalk compiler provides partial support for compiling Prolog
modules as Logtalk objects. This support may allow using modules from a backend
Prolog system in a different backend Prolog system, although its main purpose is
to help in porting existing Prolog code to Logtalk in order to benefit from its
extended language features and its developer tools. Why partial support?
Although there is an ISO Prolog standard for modules, it is (rightfully)
ignored by most implementers and vendors (due to its flaws and deviation
from common practice). In addition, there is no de facto standard for module
systems, despite otherwise frequent misleading claims. Key system differences
include the set of implemented module directives, the directive semantics, the
handling of operators, the locality of flags, and the integration of
term-expansion mechanisms (when provided). Another potential issue is that,
when compiling modules as objects, Logtalk assumes that any referenced module
(e.g., using <code class="docutils literal notranslate"><span class="pre">use_module/1-2</span></code> directives) is also being compiled as an
object. If that’s not the case, the compiled module calls being compiled as
message-sending goals will still work for normal predicates but will not
work for meta-predicates called using implicit module qualification. The
reason is that, unlike in Logtalk, calls to implicitly and explicitly
qualified module meta-predicates have different semantics. Follows a
discussion of other limitations of this approach that you should be aware of.</p>
<section id="supported-module-directives">
<span id="migration-compatibility"></span><h3>Supported module directives<a class="headerlink" href="#supported-module-directives" title="Link to this heading"></a></h3>
<p>Currently, Logtalk supports the following module directives:</p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">module/1</span></code></dt><dd><p>The module name becomes the object name.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">module/2</span></code></dt><dd><p>The module name becomes the object name. The exported predicates
become public object predicates. The exported grammar rule
non-terminals become public grammar rule non-terminals. The exported
operators become public object operators but are not active elsewhere
when loading the code.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">use_module/2</span></code></dt><dd><p>This directive is compiled as a Logtalk
<a class="reference internal" href="../refman/directives/uses_2.html#directives-uses-2"><span class="std std-ref">uses/2</span></a> directive in order
to ensure correct compilation of the module predicate clauses. The
first argument of this directive must be the module <strong>name</strong> (an
atom), not a module file specification (the adapter files attempt to
use the Prolog dialect level term-expansion mechanism to find the
module name from the module file specification). Note that the module
is not automatically loaded by Logtalk (as it would be when compiling
the directive using Prolog instead of Logtalk; the programmer may
also want the specified module to be compiled as an object). The
second argument must be a predicate indicator (<code class="docutils literal notranslate"><span class="pre">Name/Arity</span></code>), a
grammar rule non-terminal indicator (<code class="docutils literal notranslate"><span class="pre">Name//Arity</span></code>), a operator
declaration, or a list of predicate indicators, grammar rule
non-terminal indicators, and operator declarations. Predicate aliases
can be declared using the notation <code class="docutils literal notranslate"><span class="pre">Name/Arity</span> <span class="pre">as</span> <span class="pre">Alias/Arity</span></code> or,
in alternative, the notation <code class="docutils literal notranslate"><span class="pre">Name/Arity:Alias/Arity</span></code>. Similar for
non-terminal aliases.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">export/1</span></code></dt><dd><p>Exported predicates are compiled as public object predicates. The
argument must be a predicate indicator (<code class="docutils literal notranslate"><span class="pre">Name/Arity</span></code>), a grammar
rule non-terminal indicator (<code class="docutils literal notranslate"><span class="pre">Name//Arity</span></code>), an operator
declaration, or a list of predicate indicators, grammar rule
non-terminal indicators, and operator declarations.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">reexport/2</span></code></dt><dd><p>Reexported predicates are compiled as public object predicates. The
first argument is the module name. The second argument must be a
predicate indicator (<code class="docutils literal notranslate"><span class="pre">Name/Arity</span></code>), a grammar rule non-terminal
indicator (<code class="docutils literal notranslate"><span class="pre">Name//Arity</span></code>), an operator declaration, or a list of
predicate indicators, grammar rule non-terminal indicators, and
operator declarations. Predicate aliases can be declared using the
notation <code class="docutils literal notranslate"><span class="pre">Name/Arity</span> <span class="pre">as</span> <span class="pre">Alias/Arity</span></code> or, in alternative, the notation
<code class="docutils literal notranslate"><span class="pre">Name/Arity:Alias/Arity</span></code>. Similar for non-terminal aliases.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">meta_predicate/1</span></code></dt><dd><p>Module meta-predicates become object meta-predicates. All meta-predicates
must be declared using the <a class="reference internal" href="../refman/directives/meta_predicate_1.html#directives-meta-predicate-1"><span class="std std-ref">meta_predicate/1</span></a> directive
using Logtalk syntax for normal arguments and meta-arguments. Note that
Prolog module meta-predicates and Logtalk meta-predicates don’t share the
same explicit-qualification calling semantics: in Logtalk, meta-arguments
are always called in the context of the <a class="reference internal" href="../glossary.html#term-sender"><span class="xref std std-term">sender</span></a>. Moreover, Logtalk
is not based on the predicate-prefixing mechanism common to most Prolog
module systems.</p>
</dd>
</dl>
<p>A common issue when compiling modules as objects is the use of the atoms
<code class="docutils literal notranslate"><span class="pre">dynamic</span></code>, <code class="docutils literal notranslate"><span class="pre">discontiguous</span></code>, and <code class="docutils literal notranslate"><span class="pre">multifile</span></code> as operators in
directives. For better portability, avoid this usage. For example, write:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">dynamic</span>([foo<span class="o">/</span><span class="m">1</span>, bar<span class="o">/</span><span class="m">2</span>]).
</pre></div>
</div>
<p>instead of:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>:- dynamic foo/1, bar/2.
</pre></div>
</div>
<p>Another common issue is missing <code class="docutils literal notranslate"><span class="pre">meta_predicate/1</span></code>, <code class="docutils literal notranslate"><span class="pre">dynamic/1</span></code>,
<code class="docutils literal notranslate"><span class="pre">discontiguous/1</span></code>, and <code class="docutils literal notranslate"><span class="pre">multifile/1</span></code> predicate directives. The Logtalk
compiler supports detection of missing directives (by setting its
<a class="reference internal" href="programming.html#flag-missing-directives"><span class="std std-ref">missing_directives</span></a> flag to <code class="docutils literal notranslate"><span class="pre">warning</span></code>).</p>
<p>When compiling modules as objects, you probably don’t need event support
turned on. You may use the <a class="reference internal" href="programming.html#flag-events"><span class="std std-ref">events</span></a> compiler flag to
<code class="docutils literal notranslate"><span class="pre">deny</span></code> in the Logtalk compiling and loading built-in methods for a
small performance gain for the compiled code.</p>
</section>
<section id="unsupported-module-directives">
<span id="migration-unsupported-module-directives"></span><h3>Unsupported module directives<a class="headerlink" href="#unsupported-module-directives" title="Link to this heading"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">reexport/1</span></code> and <code class="docutils literal notranslate"><span class="pre">use_module/1</span></code> directives are not directly
supported by the Logtalk compiler. But most Prolog adapter files provide
support for compiling these directives using Logtalk’s first stage of
its <a class="reference internal" href="expansion.html#expansion-expansion"><span class="std std-ref">term-expansion mechanism</span></a>. Nevertheless,
these directives can be converted, respectively, into a sequence of
<code class="docutils literal notranslate"><span class="pre">:-</span> <span class="pre">use_module/2</span></code> and <code class="docutils literal notranslate"><span class="pre">export/1</span></code> directives and <code class="docutils literal notranslate"><span class="pre">use_module/2</span></code>
directives by finding which predicates exported by the
specified modules are reexported or imported into the module containing
the directive. For <code class="docutils literal notranslate"><span class="pre">use_module/1</span></code> directives, finding the names of the
imported predicates that are actually used is easy. First, comment out the
directive and compile the file (making sure that the
<a class="reference internal" href="programming.html#flag-unknown-predicates"><span class="std std-ref">unknown_predicates</span></a> compiler flag is set
to <code class="docutils literal notranslate"><span class="pre">warning</span></code>). Logtalk will print a warning with a list of predicates
that are called but never defined. Second, use this list to replace the
<code class="docutils literal notranslate"><span class="pre">use_module/1</span></code> directives by <code class="docutils literal notranslate"><span class="pre">use_module/2</span></code> directives. You should
then be able to compile the modified Prolog module as an object.</p>
</section>
<section id="modules-using-a-term-expansion-mechanism">
<span id="migration-module-expansions"></span><h3>Modules using a term-expansion mechanism<a class="headerlink" href="#modules-using-a-term-expansion-mechanism" title="Link to this heading"></a></h3>
<p>Although Logtalk supports
<a class="reference internal" href="expansion.html#expansion-expansion"><span class="std std-ref">term and goal expansion mechanisms</span></a>, the usage
semantics are different from similar mechanisms found in some Prolog
compilers. In particular, Logtalk does not support defining term and
goal expansions clauses in a source file for expanding the source file
itself. Logtalk forces a clean separation between expansion clauses and
the source files that will be subject to source-to-source expansions by
using <a class="reference internal" href="../glossary.html#term-hook-object"><span class="xref std std-term">hook objects</span></a>. But hook objects also provide
a working solution here when the expansion code is separated from the
code to be expanded. Logtalk supports using a module as a hook object
as long as its name doesn’t coincide with the name of an object and
that the module uses <code class="docutils literal notranslate"><span class="pre">term_expansion/2</span></code> and <code class="docutils literal notranslate"><span class="pre">goal_expansion/2</span></code>
predicates. Assuming that’s the case, before attempting to compile
the modules as objects, set the default hook object to the module
containing the expansion code. For example, if the expansions are stored
in a <code class="docutils literal notranslate"><span class="pre">system</span></code> module:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- set_logtalk_flag(hook, system).
...
</pre></div>
</div>
<p>This, however, may not be enough, as expansions may be stored in multiple
modules. A common example is to use a module named <code class="docutils literal notranslate"><span class="pre">prolog</span></code> for system
expansions and to store the user-defined expansions in <code class="docutils literal notranslate"><span class="pre">user</span></code>. The Logtalk
library provides a solution for these scenarios. Using the <code class="docutils literal notranslate"><span class="pre">hook_flows</span></code>
library we can select multiple hook objects or hook modules. For example,
assuming expansions stored on both <code class="docutils literal notranslate"><span class="pre">user</span></code> and <code class="docutils literal notranslate"><span class="pre">system</span></code> modules:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- logtalk_load(hook_flows(loader)).
...

| ?- set_logtalk_flag(hook, hook_set([user, system])).
...
</pre></div>
</div>
<p>After these queries, we can try to compile the modules and look for
other porting or portability issues. A well-know issue is Prolog module
term-expansions calling predicates such as <code class="docutils literal notranslate"><span class="pre">prolog_load_context/2</span></code>,
which will always fail when it’s the Logtalk compiler instead of the
Prolog compiler loading a source file. In some of these cases, it may
be possible to rewrite the expansion rules to use the
<a class="reference internal" href="../refman/predicates/logtalk_load_context_2.html#predicates-logtalk-load-context-2"><span class="std std-ref">logtalk_load_context/2</span></a> predicate instead.</p>
</section>
<section id="file-search-paths">
<span id="migration-file-search-paths"></span><h3>File search paths<a class="headerlink" href="#file-search-paths" title="Link to this heading"></a></h3>
<p>Some Prolog systems provide a mechanism for defining file search paths
(this mechanism works differently from Logtalk own support for defining
library path aliases). When porting Prolog code that defines file search
paths, e.g. for finding module libraries, it often helps to load the
pristine Prolog application before attempting to compile its source files
as Logtalk source files. Depending on the Prolog backend, this may allow
the file search paths to be used when compiling modules as objects that
use file directives such as <code class="docutils literal notranslate"><span class="pre">use_module/2</span></code>.</p>
</section>
</section>
<section id="dealing-with-proprietary-prolog-directives-and-predicates">
<span id="migration-proprietary"></span><h2>Dealing with proprietary Prolog directives and predicates<a class="headerlink" href="#dealing-with-proprietary-prolog-directives-and-predicates" title="Link to this heading"></a></h2>
<p>Most Prolog compilers define proprietary, non-standard directives and
predicates that may be used in both plain code and module code.
Non-standard Prolog built-in predicates are usually not problematic, as
Logtalk is usually able to identify and compile them correctly (but see
the notes on built-in meta-predicates for possible caveats). However,
Logtalk will generate compilation errors on source files containing
proprietary directives unless you first specify how the directives
should be handled. Several actions are possible on a per-directive
basis: ignoring the directive (i.e., do not copy the directive, although
a goal can be proved as a consequence), rewriting and copying the directive
to the generated Prolog files, or rewriting and recompiling the
resulting directive. To specify these actions, the adapter files contain
clauses for the internal <code class="docutils literal notranslate"><span class="pre">'$lgt_prolog_term_expansion'/2</span></code> predicate.
For example, assume that a given Prolog compiler defines a <code class="docutils literal notranslate"><span class="pre">comment/2</span></code>
directive for predicates using the format:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span>comment(foo<span class="o">/</span><span class="m">2</span>, <span class="s">&quot;Brief description of the predicate&quot;</span>).
</pre></div>
</div>
<p>We can rewrite this predicate into a Logtalk <code class="docutils literal notranslate"><span class="pre">info/2</span></code> directive by
defining a suitable clause for the <code class="docutils literal notranslate"><span class="pre">'$lgt_prolog_term_expansion'/2</span></code>
predicate:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="s">&#39;$lgt_prolog_term_expansion&#39;</span>(
        (<span class="o">:-</span> comment(<span class="nv">F</span><span class="o">/</span><span class="nv">A</span>, <span class="nv">String</span>)),
        (<span class="o">:-</span> info(<span class="nv">F</span><span class="o">/</span><span class="nv">A</span>, [comment <span class="k">is</span> <span class="nv">Atom</span>]))
) <span class="o">:-</span>
    <span class="k">atom_codes</span>(<span class="nv">Atom</span>, <span class="nv">String</span>).
</pre></div>
</div>
<p>This Logtalk feature can be used to allow compilation of legacy Prolog
code without the need of changing the sources. When used, it is advisable
to set the <a class="reference internal" href="programming.html#flag-portability"><span class="std std-ref">portability</span></a> compiler flag to
<code class="docutils literal notranslate"><span class="pre">warning</span></code> in order to more easily identify source files that are
likely non-portable across Prolog compilers.</p>
<p>A second example, where a proprietary Prolog directive is discarded
after triggering a side effect:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="s">&#39;$lgt_prolog_term_expansion&#39;</span>(
        (<span class="o">:-</span> load_foreign_files(<span class="nv">Files</span>,<span class="nv">Libs</span>,<span class="nv">InitRoutine</span>)),
        []
) <span class="o">:-</span>
    load_foreign_files(<span class="nv">Files</span>,<span class="nv">Libs</span>,<span class="nv">InitRoutine</span>).
</pre></div>
</div>
<p>In this case, although the directive is not copied to the generated
Prolog file, the foreign library files are loaded as a side effect of
the Logtalk compiler calling the <code class="docutils literal notranslate"><span class="pre">'$lgt_prolog_term_expansion'/2</span></code> hook
predicate.</p>
</section>
<section id="calling-prolog-module-predicates">
<span id="migration-calling"></span><h2>Calling Prolog module predicates<a class="headerlink" href="#calling-prolog-module-predicates" title="Link to this heading"></a></h2>
<p>Prolog module predicates can be called from within objects or categories
by simply using explicit module qualification, i.e. by writing
<code class="docutils literal notranslate"><span class="pre">Module:Goal</span></code> or <code class="docutils literal notranslate"><span class="pre">Goal&#64;Module</span></code> (depending on the module system).
Logtalk also supports the use of <code class="docutils literal notranslate"><span class="pre">use_module/2</span></code> directives in objects
and categories (with the restriction that the first argument of the
directive must be the actual module name and not the module file name or
the module file path). In this case, these directives are parsed in a
similar way to Logtalk <a class="reference internal" href="../refman/directives/uses_2.html#directives-uses-2"><span class="std std-ref">uses/2</span></a>
directives, with calls to the specified module predicates being
automatically translated to <code class="docutils literal notranslate"><span class="pre">Module:Goal</span></code> calls.</p>
<p>As a general rule, the Prolog modules should be loaded (e.g., in the
auxiliary Logtalk loader files) <em>before</em> compiling objects that make use
of module predicates. Moreover, the Logtalk compiler does not generate
code for the automatic loading of modules referenced in
<code class="docutils literal notranslate"><span class="pre">use_module/1-2</span></code> directives. This is a consequence of the lack of
standardization of these directives, whose first argument can be a
module name, a straight file name, or a file name using some kind of
library notation, depending on the <a class="reference internal" href="../glossary.html#term-backend-Prolog-compiler"><span class="xref std std-term">backend Prolog compiler</span></a>. Worse,
modules are sometimes defined in files with names different from the
module names, requiring finding, opening, and reading the file in order
to find the actual module name.</p>
<p>Logtalk allows you to send a message to a module in order to call one of
its predicates. This is usually not advised as it implies a performance
penalty when compared to just using the <code class="docutils literal notranslate"><span class="pre">Module:Call</span></code> notation.
Moreover, this works only if there is no object with the same name as
the module you are targeting. This feature is necessary, however, in
order to properly support the compilation of modules containing
<code class="docutils literal notranslate"><span class="pre">use_module/2</span></code> directives as objects. If the modules specified in the
<code class="docutils literal notranslate"><span class="pre">use_module/2</span></code> directives are not compiled as objects but are instead
loaded as-is by Prolog, the exported predicates would need to be called
using the <code class="docutils literal notranslate"><span class="pre">Module:Call</span></code> notation but the converted module will be
calling them through message-sending. Thus, this feature ensures that,
on a module compiled as an object, any predicate calling other module
predicates will work as expected, either these other modules are loaded
as-is or also compiled as objects.</p>
<p>For more details, see the <a class="reference internal" href="predicates.html#predicates-prolog"><span class="std std-ref">Calling Prolog predicates</span></a> section.</p>
</section>
<section id="loading-converted-prolog-applications">
<span id="migration-loading"></span><h2>Loading converted Prolog applications<a class="headerlink" href="#loading-converted-prolog-applications" title="Link to this heading"></a></h2>
<p>Logtalk strongly favors and advises users to provide a main
<a class="reference internal" href="programming.html#programming-loaders"><span class="std std-ref">loader file</span></a> for applications that explicitly
load any required libraries and the application source files. In contrast,
Prolog applications often either scatter loading of source files from multiple
files or use implicit loading of source files via <code class="docutils literal notranslate"><span class="pre">use_module/1-2</span></code>
directives. Due to this frequent ad-hoc approach, it’s common to find Prolog
applications with duplicated loading directives, and where loading order ignores
the dependencies between source files. These issues are easily exposed by the
Logtalk linter when compiling Prolog files as Logtalk files. Also common are
Prolog files with multiple circular dependencies. While this should not
affect the <em>semantics</em> of the ported code, it may cause some performance
penalties as it prevents the Logtalk compiler from optimizing the message
sending goals using static-binding. It also makes the application architecture
more difficult to understand. The definition of explicit loader files
provides a good opportunity for sorting out loading order and circular
dependencies, with the linter warnings providing hints for possible code
refactoring to eliminate these issues. The <a class="reference internal" href="../devtools/diagrams.html"><span class="doc">diagrams</span></a> tool
supports directory and file loading and dependency diagrams that are also
useful in understanding applications architecture.</p>
</section>
</section>


           </div>
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="installing.html" class="btn btn-neutral float-left" title="Installing Logtalk" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="../refman/index.html" class="btn btn-neutral float-right" title="Reference Manual" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 1998-2025, Paulo Moura.</p>
  </div>

  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
   

</footer>
        </div>
      </div>
    </section>
  </div>
  <script>
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script> 

</body>
</html>